//! @Author: DengLibin
//! @Date: Create in 2023-09-25 15:01:22
//! @Description: base64

use base64::{alphabet, engine, Engine};
use std::{
    fmt::Display,
    fs::File,
    io::{Read, Write},
};

#[derive(Debug, Clone, PartialEq)]
pub struct Base64Error {
    msg: String,
}
impl std::fmt::Display for Base64Error {
    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
        write!(f, "Message: {}", self.msg)
    }
}
// 自定义结果
pub type Base64Result<T> = std::result::Result<T, Base64Error>;

//转换结果
fn check_result<T, E: Display>(result: Result<T, E>) -> Base64Result<T> {
    return match result {
        Ok(r) => Result::Ok(r),
        Err(err) => Result::Err(Base64Error {
            msg: err.to_string(),
        }),
    };
}
/// @Author: DengLibin
/// @Date: Create in 2023-09-28 17:43:04
/// @Description: 文件转base64字符串
pub fn encode_file(file_path: &str) -> Base64Result<String> {
    //函数用于以只读模式打开一个已经存在的文件，如果文件不存在，则会抛出一个错误。如果文件不可读，那么也会抛出一个错误
    let r = File::open(file_path);
    let mut f = check_result(r)?;
    let mut buf = vec![0_u8; 0];
    //预先分配好内存，效率更高
    buf.reserve(10240);
    let engine = engine::GeneralPurpose::new(&alphabet::STANDARD, engine::general_purpose::PAD);
    check_result(f.read_to_end(&mut buf))?;
    Ok(engine.encode(buf))
}

/// @Author: DengLibin
/// @Date: Create in 2023-09-25 15:50:37
/// @Description: base64转文件
pub fn decode_to_file(file_path: &str, base64: &str) -> Base64Result<()> {
    let mut f = check_result(File::create(file_path))?;
    let engine = engine::GeneralPurpose::new(&alphabet::STANDARD, engine::general_purpose::PAD);
    let u8s = check_result(engine.decode(base64))?;
    let ws = f.write_all(&u8s);
    check_result(ws)
}

/// @Author: DengLibin
/// @Date: Create in 2023-09-25 15:18:58
/// @Description: 获取base64
pub fn encode_str(str: &str) -> String {
    let buf = str.as_bytes();
    return  encode_bytes(buf);
}
/// @Author: DengLibin
/// @Date: Create in 2024-01-18 11:51:25
/// @Description: 编码
pub fn encode_bytes(bytes: &[u8])->String {
    let engine = engine::GeneralPurpose::new(&alphabet::STANDARD, engine::general_purpose::PAD);
    return engine.encode(bytes);
}

/// @Author: DengLibin
/// @Date: Create in 2023-09-25 15:18:58
/// @Description: 解码base64
pub fn decode_to_bytes(base64: &str) -> Base64Result<Vec<u8>> {
    let engine = engine::GeneralPurpose::new(&alphabet::STANDARD, engine::general_purpose::PAD);
    check_result(engine.decode(base64))

   
}

/// @Author: DengLibin
/// @Date: Create in 2023-09-25 15:18:58
/// @Description: 解码base64
pub fn decode_to_string(base64: &str) -> Base64Result<String> {
    let v8 = decode_to_bytes(base64)?;

    check_result(String::from_utf8(v8))
}
